﻿using Microsoft.Xna.Framework;
using System;

namespace Organized
{
    public static class MathUtil
    {
        // Generates a projection matrix for a draw call
        public static Matrix CreateProjectionMatrix()
        {
            return Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Engine.GraphicsDevice.Viewport.AspectRatio, 1f, 5500.0f);
        }

        public static Matrix CreateProjectionMatrix(float fov)
        {
            return Matrix.CreatePerspectiveFieldOfView(fov, Engine.GraphicsDevice.Viewport.AspectRatio, 1f, 5500.0f);
        }

        public static Matrix CreateProjectionMatrix(float fov, float dist)
        {
            return Matrix.CreatePerspectiveFieldOfView(fov, Engine.GraphicsDevice.Viewport.AspectRatio, 1f, dist);
        }

        // Creates a world matrix, uses three functions, so your able to return a matrix with any given settings
        public static Matrix CreateWorldMatrix(Vector3 Translation)
        {
            return CreateWorldMatrix(Translation, Matrix.Identity);
        }

        public static Matrix CreateWorldMatrix(Vector3 Translation, Matrix Rotation)
        {
            return CreateWorldMatrix(Translation, Rotation, Vector3.One);
        }

        public static Matrix CreateWorldMatrix(Vector3 Translation, Matrix Rotation, Vector3 Scale)
        {
            return Matrix.CreateScale(Scale) * Rotation * Matrix.CreateTranslation(Translation);
        }

        //Converts a rotation vector into a rotation matrix
        public static Matrix Vector3ToMatrix(Vector3 Rotation)
        {
            return Matrix.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z);
        }

        //Converts a rotation matrix into a rotation vector
        public static Vector3 MatrixToVector3(Matrix Rotation)
        {
            Quaternion q = Quaternion.CreateFromRotationMatrix(Rotation);
            return new Vector3(q.X, q.Y, q.Z);
        }
        //coverts radian to 2d vector
        public static Vector2 RadianToVector2(double Angle)
        {
            Vector2 direction = new Vector2();
            direction.X = (float)Math.Cos(Angle);
            direction.Y = (float)Math.Sin(Angle);

            return direction;

        }
        //converts 2d vector to radians
        public static  double Vector2ToRadian(Vector2 Direction)
        {
            double angle = Math.Atan2((double)Direction.Y, (double)Direction.X);
            if (angle < 0)
                angle += 2 * Math.PI;

            return angle;
        }

        //a percentage between 0 to 1, comparing two distances
        public static float getLengthPercentage(float maxLength, float distance)
        {

            float percentage;

            percentage = distance / maxLength;

            return percentage;
        }

        //calculate an angle difference between two angles
        public static double calculateDifferenceBetweenAngles(double firstAngle, double secondAngle)
        {
            double angle = secondAngle - firstAngle;

            angle = ThressHoldAngle(angle);

            return angle;
        }

        //convert radian to degree
        public static float RadianToDegree(double r)
        {
            float d = (float)(r * (180 / Math.PI));

            return d;
        }

        //convert degree to radian
        public static double DegreeToRadian(float d)
        {
            double r = d * (Math.PI/180);

            return r;
        }

        public static double ThressHoldAngle(double angle)
        {

            if (angle < 0)
                angle += 2 * Math.PI;

            if (angle > (2 * Math.PI))
                angle -= 2 * Math.PI;

            return angle;
        }


        //calculates the angle between two vectors
        public static double AngleBetweenVectors2(Vector2 v1, Vector2 v2)
        {
            return ((v1.X - v2.X) > 0 ? -1 : 1) * (float)Math.Acos((double)Vector2.Dot(Vector2.Normalize(v1), Vector2.Normalize(v2)));
        }
    }
}






